#include "auxiliaire.h"

/*____________________________________________________________________________*/

/*!
 * \brief Utilisée par my_strtok_r. Dit si c est un separateur.
 */
bool isSeparateur(char c, char* separateurs){
	int i;

	for(i=0; separateurs[i]!='\0';i++)
		if (c==separateurs[i])
			return True;

	return False;
}

/*!
 * \brief Mon implementation de strtok
 */
char* my_strtok_r(char *str, char *separateurs, char **pt){

	char *ret;

	if (str==NULL) ret = *pt;
	else{
		ret = str;
		*pt = str;
	}

	if(ret[0]=='\0') return NULL;

	if (isSeparateur(ret[0], separateurs)){
		*pt += 1;
		if(str==NULL)
			return my_strtok_r(NULL, separateurs, pt );
		else
			return my_strtok_r(*pt, separateurs, pt);
	}

	for(*pt=*pt; True; *pt += 1){
		if(**pt=='\0'){
			*pt = NULL;
			break;
		}

		if(isSeparateur(**pt,separateurs)){
			**pt = '\0';
			*pt += 1;
			break;
		}
	}

	return ret;
}

/*____________________________________________________________________________*/

/*!
 * \brief Lit une ligne de stream en extrait une mot e deux numéros
 */
int read_and_parse( FILE* stream, char* outval1, int* outval2, int* outval3 ){
	char buffer[BUFFER_SIZE];
	char lasts[BUFFER_SIZE], *pt;
	char * argv[3];
	int argc;

	if (fgets(buffer, BUFFER_SIZE, stream) == NULL) {
		if (feof(stream)) {
			perror(" Fin de stdin atteinte.");
			return INERROR;
		} else if (ferror(stream)) {
			perror("Erreur sur stdin.");
			return INERROR;
		}
	}

	/* Lire les arguments */
	pt = lasts;
	argc = 0;
	if ((argv[argc++] =  my_strtok_r(buffer, " \t ", &pt)) == NULL) {
		return INERROR;
	}
	while (pt != NULL) {
		argv[argc] = my_strtok_r(NULL, " \t ", &pt);

		if (++argc >= 3)
			break;
	}

	if(argc==0){
		return 0;
	}

	if(argc>=1 && outval1!=NULL){
		strcpy(outval1,argv[0]);
	}

	if(argc>=2 && outval2!=NULL){
		*outval2 = atoi(argv[1]);
	}

	if(argc>=3 && outval3!=NULL){
		*outval3 = atoi(argv[2]);
	}

	if(argc>3)
		return 3;

	return argc;
}

/*____________________________________________________________________________*/

/*!
 * \brief Retourne un entier aléatoire.
 */
int aleat(int min, int max){
	static int seed = 0;
	int ret;

	seed += time(0)^getpid();
	srand(seed);

	ret = rand()%(max-min+1);
	ret += min;

	return ret;
}

/*____________________________________________________________________________*/

/*!
 * \brief Verifier la position d'un entier dans un tableau
 */
int position(int n, int *tableau, int taille){
	int i;

	for(i=0; i<taille; i++)
		if(tableau[i]==n)
			return i;

	return -1;
}

/*____________________________________________________________________________*/

/*!
 *  \brief Enlève le n-ème element du tableau;
 */
void enleve(int n, int *tableau, int taille){

	if(n<0 || n>=taille) return;

	if(n==0){
		int i;

		for(i=1; i<taille; i++)
			tableau[i-1] = tableau[i];

		return;
	}

	enleve(n-1, tableau+1, taille-1);
}

/*____________________________________________________________________________*/

/*!
 * \brief Ouvre un processus avec arguments arg1 e arg2 et tuyaux in et out
 */
int ouvreProc(FILE** in, FILE **out, char* fileName, char* arg1, char* arg2){

    int s;
    int tuyau_pere_fils[2],
        tuyau_fils_pere[2];
    char buffer[BUFFER_SIZE];

    if( pipe(tuyau_pere_fils) == INERROR || pipe(tuyau_fils_pere) == INERROR ){
        perror("Erreur dans pipe(). ");
        exit(EXIT_FAILURE);
    }

    s = fork();
    if (s < 0) {
        perror("Erreur dans fork(). ");
        exit(EXIT_FAILURE);
    }

    else if (s == 0){

        close(tuyau_fils_pere[Lecture]);
        /* Branche le cote écriture du tuyau comme sortie standard */
        if (dup2(tuyau_fils_pere[Ecriture], STDOUT_FILENO) == -1) {
            perror("Erreur dans dup2() pour écrire");
            exit(EXIT_FAILURE);
        }
        close(tuyau_fils_pere[Ecriture]);

        close(tuyau_pere_fils[Ecriture]);
        /* Branche le cote lecture du tuyau comme entré standard */
        if (dup2(tuyau_pere_fils[Lecture], STDIN_FILENO) == -1){
            perror("Erreur dans dup2() pour lire");
            exit(EXIT_FAILURE);
        }
        close(tuyau_pere_fils[Lecture]);

        sprintf(buffer,"./%s",fileName);
        if ( execlp(buffer, fileName, arg1, arg2, NULL) == INERROR ){
            perror("Errer avec execlp().");
            exit(EXIT_FAILURE);
        }
    }

    else{
        int tuyau[2];

        close(tuyau_fils_pere[Ecriture]);
        close(tuyau_pere_fils[Lecture]);

        tuyau[Lecture ]  = tuyau_fils_pere[Lecture];
        tuyau[Ecriture]  = tuyau_pere_fils[Ecriture];

        *in  = fdopen(tuyau[Lecture],"r");
        if(in==NULL){
            perror("Erreur en ouvrant le tuyau en lecture.");
            exit(EXIT_FAILURE);
        }

        *out = fdopen(tuyau[Ecriture],"w");
        if(out==NULL){
            perror("Erreur en ouvrant le tuyau en écriture.");
            exit(EXIT_FAILURE);
        }
        return s;
    }


}

/*____________________________________________________________________________*/
